package atag.gui;
/*
 * NetworkGraph.java
 *
 * Created on June 1, 2007, 4:52 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

/**
 *
 * @author Sirius
 */
import atag.runtimeForGUI.NodeInfo;
import atag.runtimeForGUI.NodeLocation;
import atag.runtime.ln.nodeAttributesForGUI.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;		// For Ellipse2D, etc.
import java.util.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.event.*;
import javax.swing.BorderFactory; 
import javax.swing.border.Border;
import java.lang.Math;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import networkTopo.NetworkTopo;
import networkTopo.NodeIDGroup;




public class NetworkGraph extends JPanel
{

    /** Creates a new instance of NetworkGraph */
   //selected, related, global
    private NetworkTopo m_networkTopo;
    private int m_selectedNodeType = -1;
    private int m_selectedNodeID = -1;
    private int m_pressedNodeID = -1;
    private int m_pressedNodeType = -1;
    final static Color red = Color.red;
    final static Color white = Color.white;
    final static Color fg = Color.black;
    private boolean m_isFileLoaded = false;
    private boolean m_doShowSelectedNodesRadioRange = false;
    private boolean m_doShowSelectedNodesRadioLink = false;
    private boolean m_doShowSelectedNodesID = false;
    private boolean m_doShowGlobalNodeIDs = false;
    private boolean m_doShowGlobalRadioRange = false;
    private boolean m_doShowGlobalRadioLink = false;
    private boolean m_doShowNewNodes = false;
//    private boolean m_doShowNewNodes = true;
    
    private String m_GUI_BasePath;
    private NodeIDGroup m_selectedNodeIDGroup;
    private NodeIDGroup m_compensateGlobalNodeIDGroup;// 
    private NodeIDGroup m_globalNodeIDGroup;
    private Properties props;

 
    public ArrayList<NodeInfo> m_newNodes;


    
    //private 
    //this.
    
    public ArrayList<NodeInGraphInfo> m_graphicNodes;
    public ArrayList<NodeInGraphInfo> m_graphicNewNodes;
    
    public void setGUIBasePath (String path) {
        System.err.println("GUI base path now set to "+path);
        this.m_GUI_BasePath = path;
    }

    public String getGUIBasePath(){
        return this.m_GUI_BasePath;
    }
    
    public int getSelectedNodeID() {
        //m_isFileLoaded = isFileLoaded;
        return(this.m_selectedNodeID);
    }
    
    public int getSelectedNodeType() {
        //m_isFileLoaded = isFileLoaded;
        return(this.m_selectedNodeType);
    }
    
    public int getPressedNodeID() {
        //m_isFileLoaded = isFileLoaded;
        return(this.m_pressedNodeID);
    }
    
    public int getPressedNodeType() {
        //m_isFileLoaded = isFileLoaded;
        return(this.m_pressedNodeType);
    }
    
    
    public void setIsFileLoadedFlag(boolean isFileLoaded) {
        m_isFileLoaded = isFileLoaded;
        repaint();
    }
    
    public boolean isFileLoaded() {
        return this.m_isFileLoaded;
    }
    
    public void setDoShowGlobalNodeIDs(boolean doShowGlobalNodeIDs) {
        this.m_doShowGlobalNodeIDs = doShowGlobalNodeIDs;
        repaint();
    }
    
    public void setDoShowIndividualRadioRange(boolean doShowSelectedNodesRadioRange) {
        this.m_doShowSelectedNodesRadioRange = doShowSelectedNodesRadioRange;
        repaint();
    }
    
    public void setDoShowIndividualRadioLink(boolean doShowSelectedNodesRadioLink) {
        this.m_doShowSelectedNodesRadioLink = doShowSelectedNodesRadioLink;
        repaint();
    }
    
    public void setConfirmNodeChanges(int nodeType) {
        //this.m_doShowSelectedNodesRadioLink = doShowSelectedNodesRadioLink;
        if (this.m_selectedNodeID != -1 && nodeType == Constants.NODE_TYPE_COMPLETED && this.m_selectedNodeType == Constants.NODE_TYPE_COMPLETED) {
            repaint();
            return;
        }
        if (this.m_selectedNodeID != -1 && nodeType == Constants.NODE_TYPE_PROTOTYPE && this.m_selectedNodeType == Constants.NODE_TYPE_PROTOTYPE) {
            this.m_newNodes.remove(this.m_selectedNodeID);
            this.m_selectedNodeID = this.m_networkTopo.getNodes().size()-1;
            this.m_selectedNodeType = Constants.NODE_TYPE_COMPLETED;
            repaint();
            return;
        }
    }
    
    public void setDoShowGlobalRadioRange(boolean doShowGlobalRadioRange) {
        
        this.m_doShowGlobalRadioRange = doShowGlobalRadioRange;
        repaint();
    }
    
    public void setDoShowIndividualNodeID(boolean doShowSelectedNodesID) {
        this.m_doShowSelectedNodesID = doShowSelectedNodesID;
        repaint();
    }
    
    public void setDoShowGlobalRadioLink(boolean doShowGlobalRadioLink) {
        this.m_doShowGlobalRadioLink = doShowGlobalRadioLink;
        repaint();
    }
        
    public void setSingleSelectedNodeID(int id) { // only for existed node but not new node
        m_selectedNodeID = id;
        m_selectedNodeType = Constants.NODE_TYPE_COMPLETED;
        //System.out.println("selected node tpye " + m_selectedNodeType);
        //m_selectedNodeIDGroup.clearAllNodeIDs();
        m_selectedNodeIDGroup.addNodeID(id);
        repaint();
    }
    
    public void setSingleSelectedNewNodeID(int id) { // only for existed node but not new node
        m_selectedNodeID = id;
        m_selectedNodeType = Constants.NODE_TYPE_PROTOTYPE;
        //System.out.println("selected node tpye " + m_selectedNodeType);
        //m_selectedNodeIDGroup.clearAllNodeIDs();
        //m_selectedNodeIDGroup.addNodeID(id);
        repaint();
    }
    
    public NetworkGraph(Properties props) {
        m_compensateGlobalNodeIDGroup = new NodeIDGroup();
        m_selectedNodeIDGroup = new NodeIDGroup();
        m_globalNodeIDGroup = new NodeIDGroup();
        m_graphicNodes = new ArrayList<NodeInGraphInfo>();
        m_graphicNewNodes = new ArrayList<NodeInGraphInfo>();
        m_newNodes = new ArrayList<NodeInfo>();
        m_globalNodeIDGroup.setGlobalNodeIDs();
        this.props = props;
         //m_globalNodeIDGroup.setGlobalNodeIDs();
        
        this.setBackground(Color.white);
        this.setVisible(true);
        this.addMouseListener(new MyMouseListener());
        this.addMouseMotionListener(new MyMouseMotionListener());
        //addMouseListener();
    }
    
    public void setData (NetworkTopo networkTopo) {
        m_networkTopo = networkTopo;
        //System.out.println(m_networkTopo.getXRange());
    }
    

    /**
     * Holds value of property networkGraph.
     */
    private String networkGraph;

    //public void paint(Graphics g) {
    
    //}
    
    
    private void paintRadioLink(NodeIDGroup nodeIDGroup, Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        int src_X;
        int src_Y;
        int dst_X;
        int dst_Y;
        
        if(!nodeIDGroup.isGlobal()) {
            for (int i = 0; i < nodeIDGroup.nodeIDs.size(); i++) {
                int c_nodeID = nodeIDGroup.nodeIDs.get(i).intValue();
                for (int j = 0; j <m_networkTopo.nnodes; j++) {
                    if (m_networkTopo.nbhood[c_nodeID][j] == 1) {
                        int src_CenterX = this.m_graphicNodes.get(c_nodeID).Xcoord;// + (Constants.NODE_IMAGE_WIDTH/2);
                        int src_CenterY = this.m_graphicNodes.get(c_nodeID).Ycoord;// + (Constants.NODE_IMAGE_HEIGHT/2);
                        int dst_CenterX = this.m_graphicNodes.get(j).Xcoord;// + (Constants.NODE_IMAGE_WIDTH/2);
                        int dst_CenterY = this.m_graphicNodes.get(j).Ycoord;// + (Constants.NODE_IMAGE_HEIGHT/2);
                    
                        double xdist = Math.pow((double) (dst_CenterX - src_CenterX), 2.0);
                        double ydist = Math.pow((double) (dst_CenterY - src_CenterY), 2.0);
                        double xydist = Math.sqrt(xdist + ydist);
                        //int dst_CenterY = this.m_graphicNodes.get(j).Xcoord
                        double cosValue = ((double) (dst_CenterX - src_CenterX))/xydist;
                        double angleX = Math.acos(cosValue);
                        double sinValue = ((double) (dst_CenterY - src_CenterY))/xydist;
                        double angleY = Math.asin(cosValue);
                        src_X =(int) (Constants.NODE_IMAGE_RADIOLINK_INTERVAL*cosValue + src_CenterX);
                        dst_X =(int) (dst_CenterX - Constants.NODE_IMAGE_RADIOLINK_INTERVAL*cosValue);
                        src_Y =(int) (Constants.NODE_IMAGE_RADIOLINK_INTERVAL*sinValue + src_CenterY);
                        dst_Y =(int) (dst_CenterY - Constants.NODE_IMAGE_RADIOLINK_INTERVAL*sinValue);
                    
                        g2.setColor(Color.black);
                        //System.out.println(src_X +" " + src_Y + " "+ dst_X + " "+ dst_Y);
                        g2.drawLine(src_X, src_Y, dst_X, dst_Y);
                        //System.out.println("print line 00");
                    }
                }
            }
            //System.out.println("print line 2");
            //System.out.println("print line 2");
        }
        else {
             for (int i = 0; i < m_networkTopo.nnodes; i ++) {
                 int c_nodeID = i;
                 for (int j = 0; j <m_networkTopo.nnodes; j++) {
                    if (m_networkTopo.nbhood[c_nodeID][j] == 1) {
                        int src_CenterX = this.m_graphicNodes.get(c_nodeID).Xcoord;// + (Constants.NODE_IMAGE_WIDTH/2);
                        int src_CenterY = this.m_graphicNodes.get(c_nodeID).Ycoord;// + (Constants.NODE_IMAGE_HEIGHT/2);
                        int dst_CenterX = this.m_graphicNodes.get(j).Xcoord;// + (Constants.NODE_IMAGE_WIDTH/2);
                        int dst_CenterY = this.m_graphicNodes.get(j).Ycoord;// + (Constants.NODE_IMAGE_HEIGHT/2);
                    
                        double xdist = Math.pow((double) (dst_CenterX - src_CenterX), 2.0);
                        double ydist = Math.pow((double) (dst_CenterY - src_CenterY), 2.0);
                        double xydist = Math.sqrt(xdist + ydist);
                        //int dst_CenterY = this.m_graphicNodes.get(j).Xcoord
                        double cosValue = ((double) (dst_CenterX - src_CenterX))/xydist;
                        double angleX = Math.acos(cosValue);
                        double sinValue = ((double) (dst_CenterY - src_CenterY))/xydist;
                        double angleY = Math.asin(cosValue);
                        src_X =(int) (Constants.NODE_IMAGE_RADIOLINK_INTERVAL*cosValue + src_CenterX);
                        dst_X =(int) (dst_CenterX - Constants.NODE_IMAGE_RADIOLINK_INTERVAL*cosValue);
                        src_Y =(int) (Constants.NODE_IMAGE_RADIOLINK_INTERVAL*sinValue + src_CenterY);
                        dst_Y =(int) (dst_CenterY - Constants.NODE_IMAGE_RADIOLINK_INTERVAL*sinValue);
                    
                        g2.setColor(Color.black);
                        //System.out.println(src_X +" " + src_Y + " "+ dst_X + " "+ dst_Y);
                        g2.drawLine(src_X, src_Y, dst_X, dst_Y);
                        //System.out.println("print line 00");
                    }
                }
             }
        }
        //System.out.println("print line 3");
    } 
    
    private void paintNodeIDs(NodeIDGroup nodeIDGroup, Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        if (!nodeIDGroup.isGlobal()) {
            for (int i = 0; i < nodeIDGroup.nodeIDs.size(); i++) {
                int c_nodeID = nodeIDGroup.nodeIDs.get(i).intValue();
                int c_node_graphicCenterX =(int) (m_graphicNodes.get(c_nodeID).Xcoord);// + Constants.NODE_IMAGE_WIDTH/2);
                int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord);// + Constants.NODE_IMAGE_HEIGHT/2);  
              
                int idX = c_node_graphicCenterX-6;
                int idY = c_node_graphicCenterY+24;
                  //AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.3);
                  //g2.setComposite(ac);
                g2.setColor(Color.blue);
                  //g2.fillOval(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                  //int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord + Constants.NODE_IMAGE_HEIGHT/2);      
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
                g2.setComposite(ac);
                g2.drawString("[" + m_graphicNodes.get(c_nodeID).myId + "]", idX, idY);
            }
         }
         else {
              for (int i = 0; i < m_networkTopo.nnodes; i++) {
                  //int c_nodeID = nodeIDGroup.nodeIDs.get(i).intValue();
                  //NodeLocation c_node_location = c_nodes.get(i).getMyLocation();
                  //Collection c_node_attribute = c_nodes.get(i).getNodeAttributes();
                  //System.out.println(displayScale + " " + c_node_location.getY());
                  int c_nodeID = m_graphicNodes.get(i).getGraphNodeID();
                  int c_node_graphicCenterX =(int) (m_graphicNodes.get(i).Xcoord);// + Constants.NODE_IMAGE_WIDTH/2);
                  int c_node_graphicCenterY =(int) (m_graphicNodes.get(i).Ycoord);// + Constants.NODE_IMAGE_HEIGHT/2);  
              
                  int idX = c_node_graphicCenterX-6;
                  int idY = c_node_graphicCenterY+24;
                  //AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.3);
                  //g2.setComposite(ac);
                  g2.setColor(Color.blue);
                  //g2.fillOval(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                  //int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord + Constants.NODE_IMAGE_HEIGHT/2);      
                  AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
                  g2.setComposite(ac);
                  g2.drawString("[" + m_graphicNodes.get(i).myId + "]", idX, idY);
                }
            }
    }
    
    private void paintGlobalNodePhysicalAddress(Graphics g) {
        for (int i = 0; i < m_networkTopo.nnodes; i++) {
                //int c_nodeID = nodeIDGroup.nodeIDs.get(i).intValue();
                Graphics2D g2 = (Graphics2D) g;
                //NodeLocation c_node_location = c_nodes.get(i).getMyLocation();
                //Collection c_node_attribute = c_nodes.get(i).getNodeAttributes();
                //System.out.println(displayScale + " " + c_node_location.getY());
                int c_node_graphicCenterX =(int) (m_graphicNodes.get(i).Xcoord);// + Constants.NODE_IMAGE_WIDTH/2);
                int c_node_graphicCenterY =(int) (m_graphicNodes.get(i).Ycoord);// + Constants.NODE_IMAGE_HEIGHT/2);  
                
                int idX = c_node_graphicCenterX-60;
                int idY = c_node_graphicCenterY+40;
                //AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.3);
                //g2.setComposite(ac);
                g2.setColor(Color.blue);
                //g2.fillOval(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                //int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord + Constants.NODE_IMAGE_HEIGHT/2);      
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
                g2.setComposite(ac);
                String nPhyAddress = this.m_networkTopo.getNodes().get(i).getPhysicalAddress();
                g2.drawString("[" + nPhyAddress + "]", idX, idY);
         }
        
    }
    
    private void paintRadioRange(NodeIDGroup nodeIDGroup, Graphics g) {
        //int nodeX = m_graphicNodes.get(nodeId).Xcoord;
        //int nodeY = m_graphicNodes.get(nodeId).Ycoord;
//         BufferedImage img = null;
//        //Image original_img = null;
//        try {
//            img = ImageIO.read(new File("D:\\Projects\\Sensor Network\\Network_GUI\\NetworkDescriptionGUI\\src\\SunSpot.gif"));
//            //Bimg = ImageIO.read(new File("D:\\Projects\\Sensor Network\\Network_GUI\\NetworkDescriptionGUI\\src\\sensornode.jpg"));
//            //img.getSize();
//            //System.out.println(img.getHeight);
//
//        } catch (IOException e) {
//            System.out.println("image not found");
//        }
        Graphics2D g2 = (Graphics2D) g;
        if (!nodeIDGroup.isGlobal()) {
            for (int i = 0; i < nodeIDGroup.nodeIDs.size(); i++) {
                int c_nodeID = nodeIDGroup.nodeIDs.get(i).intValue();
                //Graphics2D gbi = img.createGraphics();
                //NodeLocation c_node_location = c_nodes.get(i).getMyLocation();
                //Collection c_node_attribute = c_nodes.get(i).getNodeAttributes();
                //System.out.println(displayScale + " " + c_node_location.getY());
                
                
                int c_node_graphicCenterX =(int) (m_graphicNodes.get(c_nodeID).Xcoord);// + Constants.NODE_IMAGE_WIDTH/2);
                int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord);// + Constants.NODE_IMAGE_HEIGHT/2);      
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.2);
                g2.setComposite(ac);
                g2.setColor(Color.green);
                
                //Ellipse2D rangeGraph = new Ellipse2D.Double(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                //Graphics2D rangeGraphGraphics = rangeGraph.getGraphics();
                //g2.fill(rangeGraph);
                
                g2.fillOval(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                //AlphaComposite ac1 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
                //g2.setComposite(ac1);
                //g2.setColor(Color.green);
                //g2.fillOval(c_node_graphicCenterX-10, c_node_graphicCenterY-10, 2*10, 2*10);
                
                //g2.drawImage(img, m_graphicNodes.get(c_nodeID).Xcoord, m_graphicNodes.get(c_nodeID).Ycoord, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
            }
        }
        else {
            for (int i = 0; i < m_networkTopo.nnodes; i++) {
                int c_nodeID = i;
                //Graphics2D gbi = img.createGraphics();
                //NodeLocation c_node_location = c_nodes.get(i).getMyLocation();
                //Collection c_node_attribute = c_nodes.get(i).getNodeAttributes();
                //System.out.println(displayScale + " " + c_node_location.getY());
                int c_node_graphicCenterX =(int) (m_graphicNodes.get(c_nodeID).Xcoord + Constants.NODE_IMAGE_WIDTH/2);
                int c_node_graphicCenterY =(int) (m_graphicNodes.get(c_nodeID).Ycoord + Constants.NODE_IMAGE_HEIGHT/2);      
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.3);
                g2.setComposite(ac);
                g2.setColor(Color.green);
                g2.fillOval(c_node_graphicCenterX-m_networkTopo.getRadioRange(), c_node_graphicCenterY-m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange(), 2*m_networkTopo.getRadioRange());
                //g2.drawImage(img, m_graphicNodes.get(c_nodeID).Xcoord, m_graphicNodes.get(c_nodeID).Ycoord, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
            }
        
        }
    }
    
    private void paintAllNodes(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        BufferedImage img = null;
        BufferedImage img1 = null;
        BufferedImage img2 = null;

        try {
            System.out.println("Loading images");
            img = ImageIO.read(new File(System.getProperty("user.home")+System.getProperty("file.separator")+props.getProperty("icons_dir")+System.getProperty("file.separator")+props.getProperty("sunspot")));
            img1 = ImageIO.read(new File(System.getProperty("user.home")+System.getProperty("file.separator")+props.getProperty("icons_dir")+System.getProperty("file.separator")+props.getProperty("pc")));
            img2 = ImageIO.read(new File(System.getProperty("user.home")+System.getProperty("file.separator")+props.getProperty("icons_dir")+System.getProperty("file.separator")+props.getProperty("android")));

        } catch (IOException e) {
            System.out.println("image not found");
        }
        if (m_isFileLoaded==true) {
            Iterator it = this.m_networkTopo.getNodes().iterator();
            for (int i = 0; i < this.m_networkTopo.nnodes; i++) {
                NodeInfo node = (NodeInfo)it.next();
                System.out.println("Craeting the Network Graph.Load node:"+node.toString());
                int c_nodeID = i;
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
                g2.setComposite(ac);
                if ( node.getPhysicalAddress().startsWith("0014.4F01")){
                    g2.drawImage(img, m_graphicNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2, m_graphicNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
                }
                else if (node.getAttributeByName("type").toString().startsWith("android")){
                    g2.drawImage(img2, m_graphicNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2, m_graphicNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
                }else{//j2se or hostspot
                   g2.drawImage(img1, m_graphicNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2, m_graphicNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
                }
            }
            }
        }
        
       private void paintNewNodes(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        BufferedImage img = null;

        if (m_isFileLoaded==true || m_isFileLoaded==false) {
            for (int i = 0; i < this.m_graphicNewNodes.size(); i++) {
                int c_nodeID = i;
                AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.5);
                g2.setComposite(ac);
                g2.drawImage(img, (int) (this.m_graphicNewNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2), (int) (this.m_graphicNewNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2), Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
                //System.out.println("now draw a new node!\n");
            }
        }
    }
    
    public void paintCurrentSelectedNode(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        BufferedImage img = null;

        if (m_isFileLoaded==true && this.m_selectedNodeID != -1 && this.m_selectedNodeType == Constants.NODE_TYPE_COMPLETED) {
            int c_nodeID = this.m_selectedNodeID;
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0);
            g2.setComposite(ac);
            g2.drawImage(img, m_graphicNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2-1, m_graphicNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2-1, Constants.NODE_IMAGE_WIDTH+2, Constants.NODE_IMAGE_HEIGHT+2, null);
            //System.out.println("selected printing");
        }
        if (m_isFileLoaded==true && this.m_selectedNodeID != -1 && this.m_selectedNodeType == Constants.NODE_TYPE_PROTOTYPE) {
            int c_nodeID = this.m_selectedNodeID;
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.5);
            g2.setComposite(ac);
            g2.drawImage(img, m_graphicNewNodes.get(c_nodeID).Xcoord-Constants.NODE_IMAGE_WIDTH/2-1, m_graphicNewNodes.get(c_nodeID).Ycoord-Constants.NODE_IMAGE_HEIGHT/2-1, Constants.NODE_IMAGE_WIDTH+2, Constants.NODE_IMAGE_HEIGHT+2, null);
            //System.out.println("selected printing");
        }
        //Ellipse2D ellipse = new Ellipse2D.Double(1, 2, 3, 4);
        //ellipse.con
    }
    
    
    public void paintComponent(Graphics g) {
      
        super.paintComponent(g);
        //super.paintComponent(Graphics g);
        Graphics2D g2 = (Graphics2D) g;
        Dimension size = this.getSize();
        //System.out.println(size.getWidth() + " " + size.getHeight());
        //Image img2 = null;
        //img2.
        
        //Image img = null;
     
        //Image original_img = null;
 
       //System.out.println(m_isFileLoaded);
       
       if (m_isFileLoaded == true) {
           m_graphicNodes = new ArrayList<NodeInGraphInfo>();
           //m_graphicNodes = new ArrayList<NodeInGraphInfo>();
           ArrayList<NodeInfo> c_nodes = m_networkTopo.getNodes();
           //System.out.println(m_networkTopo.getNumberOfNodes());
           for (int i = 0; i < m_networkTopo.getNumberOfNodes(); i++) {
                int c_node_ID = i;
                int c_nodeID =c_nodes.get(i).getMyId();
                NodeLocation c_node_location = c_nodes.get(i).getMyLocation();
                Collection c_node_attribute = c_nodes.get(i).getNodeAttributes();
                //System.out.println(displayScale + " " + c_node_location.getY());
                int c_node_scaledLocationX =(int) (c_node_location.getX()*Constants.NODE_IMAGE_DISTANCE_SCALE);
                int c_node_scaledLocationY =(int) (c_node_location.getY()*Constants.NODE_IMAGE_DISTANCE_SCALE);
                NodeInGraphInfo graphicNode = new NodeInGraphInfo(c_nodeID, c_node_scaledLocationX, c_node_scaledLocationY);
//                
//                graphicNode.Xcoord = c_node_scaledLocationX;
//                graphicNode.Ycoord = c_node_scaledLocationY;
//                graphicNode.myId = c_nodeID;
               
                //Graphics2D imgGraphics = img.createGraphics();
                //org.jgraph.graph.EdgeRenderer edge;
                //imgGraphics.setStroke()
                //graphicNode.myGraphics = imgGraphics;
                m_graphicNodes.add(graphicNode);
                if (i!=0)
                {    //System.out.println("Graphics node XY " + m_graphicNodes.get(i-1).Xcoord);
                     //System.out.println("Graphics node XY " + m_graphicNodes.get(i).Xcoord);
                }
                //System.out.println("Graphics node Size " + m_graphicNodes.size());
    
//    e.setFrame(x + 100, y, w, h);
//    g2.setPaint(Color.black);
//    g2.setStroke(new BasicStroke(8));
//    g2.draw(e);
//                imgGraphics.setStroke(new BasicStroke(8));
//                float[] scales = { 1f, 1f, 1f, 0.5f };
//   float[] offsets = new float[4];
//   RescaleOp rop = new RescaleOp(scales, offsets, null);
//    g2.drawImage(img, rop, 0, 0);

                //g2D.drawImage(img, null, c_node_scaledLocationX, c_node_scaledLocationY);
                //brighten(img1);
                //g2D.dispose();
               
                //g2.drawImage(img, c_node_scaledLocationX, c_node_scaledLocationY, Constants.NODE_IMAGE_WIDTH, Constants.NODE_IMAGE_HEIGHT, null);
                //g2.drawImage(img, null, c_node_scaledLocationX, c_node_scaledLocationY);
           }
           m_graphicNewNodes = new ArrayList<NodeInGraphInfo>();
           for (int i = 0; i < this.m_newNodes.size(); i ++) {
               //int c_node_ID = c_nodes.get(i).getMyId();
               NodeLocation c_node_location = this.m_newNodes.get(i).getMyLocation();
               Collection c_node_attribute = this.m_newNodes.get(i).getNodeAttributes();
               int c_node_ID = this.m_newNodes.get(i).getMyId();//different from the c_nodeID
               //System.out.println(displayScale + " " + c_node_location.getY());
               int c_node_scaledLocationX =(int) (c_node_location.getX()*Constants.NODE_IMAGE_DISTANCE_SCALE);
               int c_node_scaledLocationY =(int) (c_node_location.getY()*Constants.NODE_IMAGE_DISTANCE_SCALE);
               NodeInGraphInfo graphicNewNode = new NodeInGraphInfo(c_node_ID, c_node_scaledLocationX, c_node_scaledLocationY);
               
               //Graphics2D imgGraphics = img.createGraphics();
               //org.jgraph.graph.EdgeRenderer edge;
               //imgGraphics.setStroke()
               //graphicNode.myGraphics = imgGraphics;
               m_graphicNewNodes.add(graphicNewNode);
           
           }
       }
       
       if (m_doShowSelectedNodesID==true) {
           if (m_selectedNodeIDGroup.globalFlag != 0) {
               paintNodeIDs(m_selectedNodeIDGroup, g);                 
           }
        }
       
       
       
       if (m_doShowSelectedNodesRadioRange==true) {
           if (m_selectedNodeIDGroup.globalFlag != 0) {
               paintRadioRange(m_selectedNodeIDGroup, g);                 
           }
        }
       
     
        if (m_doShowGlobalRadioRange==true) {
            m_compensateGlobalNodeIDGroup.clearAllNodeIDs();
            for (int i = 0; i < m_networkTopo.nnodes; i++) {
                if(m_selectedNodeIDGroup.isNodeIDIncluded(i)==false) {
                   m_compensateGlobalNodeIDGroup.addNodeID(i);
                }
            }
            paintRadioRange(m_compensateGlobalNodeIDGroup ,g);
        }
        
        if (m_doShowSelectedNodesRadioLink==true) {
           if (m_selectedNodeIDGroup.globalFlag != 0) {
               paintRadioLink(m_selectedNodeIDGroup, g);     
               //System.out.println("prepare paint line");
           }
        }
        
        if (m_doShowGlobalRadioLink==true) {
            m_compensateGlobalNodeIDGroup.clearAllNodeIDs();
            for (int i = 0; i < m_networkTopo.nnodes; i++) {
                if(m_selectedNodeIDGroup.isNodeIDIncluded(i)==false) {
                   m_compensateGlobalNodeIDGroup.addNodeID(i);
                }
            }
            if (m_doShowSelectedNodesRadioLink == true)
                paintRadioLink(m_compensateGlobalNodeIDGroup ,g);
            else {
                paintRadioLink(m_globalNodeIDGroup, g);
                //System.out.println("into global print link");
            }
        }
        
        if (m_doShowGlobalNodeIDs==true) {
            m_compensateGlobalNodeIDGroup.clearAllNodeIDs();
            for (int i = 0; i < m_networkTopo.nnodes; i++) {
                if(m_selectedNodeIDGroup.isNodeIDIncluded(i)==false) {
                   m_compensateGlobalNodeIDGroup.addNodeID(i);
                }
            }
            if (m_doShowSelectedNodesRadioLink == true)
                paintNodeIDs(m_compensateGlobalNodeIDGroup ,g);
            else {
                paintNodeIDs(m_globalNodeIDGroup, g);
                //System.out.println("into global print link");
            }
            //paintGlobalNodeIDs(g);
            //paintGlobalNodePhysicalAddress(g);
        }
         
         this.paintAllNodes(g);
         this.paintCurrentSelectedNode(g);
         
         if(this.m_doShowNewNodes == true) {
            //System.out.println("do show new nodes....\n");
            this.paintNewNodes(g);
         }
    }
    
    public static void brighten(BufferedImage bi) {
        float scaleFactor = 1.5f;
        RenderingHints hints = new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        RescaleOp op = new RescaleOp(scaleFactor, 0, hints);
        op.filter(bi, bi);
    }

/*
          class Display extends JPanel implements MouseListener {
            // A nested class to represent the drawing surface that
            // fills the applet.

         Display() {
                // This constructor simply sets the background color
                // of the panel to be black and sets the panel to
                // listen for mouse events on itself.
             setBackground(Color.black);
             addMouseListener(this);
         }

        //this.addMouseListener(new MouseListener());
        public void mousePressed(MouseEvent evt) {
              // When user presses the mouse, tell the system to
              // call the drawing surface's paintComponent() method.
          //System.out.println("mouse Clicked");
       }*/
    /**
     * Getter for property networkGraph.
     * @return Value of property networkGraph.
     */
    public String getNetworkGraph() {
        return this.networkGraph;
    }

    /**
     * Setter for property networkGraph.
     * @param networkGraph New value of property networkGraph.
     */
    public void setNetworkGraph(String networkGraph) {
        this.networkGraph = networkGraph;
    }
    
    public void initializeNewNode() {

        int nid = Constants.NEW_NODE_INITIAL_ID - this.m_newNodes.size();
        String nPhysicalAddress = "";
        int nx = Constants.NODE_IMAGE_NEW_X;
        int ny = Constants.NODE_IMAGE_NEW_Y;
        NodeLocation nNodeLocation = new NodeLocation(nx, ny);
        Vector attributes = new Vector();
        IntegerAttribute regionInfo = new IntegerAttribute("none", -1);
        attributes.add(regionInfo);
        //nPhysicalAddress.spli
        String[] abilities = {"none"};
        SetAttribute abilityInfo = new SetAttribute("hardware", abilities);
        NodeInfo newNodeInfo = new NodeInfo(nid,nPhysicalAddress, nNodeLocation, attributes);   
        m_newNodes.add(newNodeInfo);
        repaint();
    }

   /* public void addMouseListener(MouseListener l) {
        //System.out.println("hehe");
    }*/
    
    /**
     *  
     * @param x x coordinate of mouse click
     * @param y y coordinate of mouse click
     * @return ID of node pointed to by the mouse
     */
    private int getSelectedNodeIndexInExistingdNodes(int x, int y) {
        int selectedNodeID = -1;
        for (int nid=0; nid < m_networkTopo.nnodes; nid++) {
            if (m_graphicNodes.get(nid).contains(x, y)) {
                selectedNodeID = nid;//m_networkTopo.getNodes().get(nid).getMyId();
                break;
            }
        }        
        return selectedNodeID;
    }
    
     private int getSelectedNodeIndexInNewNodes(int x, int y) {
        int selectedNodeID = -1;
        for (int nid=0; nid < m_newNodes.size(); nid++) {
            if (m_graphicNewNodes.get(nid).contains(x, y)) {
                selectedNodeID = nid;//m_networkTopo.getNodes().get(nid).getMyId();
                break;
            }
        }        
        return selectedNodeID;
    }
     
     
    class MyMouseListener extends MouseAdapter {
        //int selectedNodeType = -1;
        int selectedNodeIndex = -1;
        public void mouseClicked(MouseEvent e) {
            //System.out.println("mouse click detected\n");
            if (isFileLoaded()) {
            //System.out.println("clicked");
                Point mousePt = e.getPoint();
            //System.out.println("nodes number" + m_networkTopo.nnodes);
            // resolve into which node was clicked; based on diameter of circle
                int clickedX = (int)mousePt.getX();
                int clickedY = (int)mousePt.getY();
                selectedNodeIndex = getSelectedNodeIndexInExistingdNodes(clickedX, clickedY);
                if (selectedNodeIndex != -1) {
                    //selectedNodeType = NetworkGraph.NODE_TYPE_COMPLETED;
                    //System.out.println("mouse clicked on node " + selectedNodeIndex +" detected\n");
                    setSingleSelectedNodeID(selectedNodeIndex);
                    return;
                }
                //if not return
                selectedNodeIndex = getSelectedNodeIndexInNewNodes(clickedX, clickedY);
                if (selectedNodeIndex != -1) {
                    //System.out.println("mouse clicked on new node detected\n");
                    setSingleSelectedNewNodeID(selectedNodeIndex);
                    return;
                    //selectedNodeIndex = getSelectedNodeIndexInNewNodes(clickedX, clickedY);
                    //return;
                }
            }
        }
        
        public void mousePressed(MouseEvent e) {
            //System.out.println("mouse press detected\n");
            int pressedNodeID;
            if (isFileLoaded()) {
            //System.out.println("clicked");
                Point mousePt = e.getPoint();
            //System.out.println("nodes number" + m_networkTopo.nnodes);
            // resolve into which node was clicked; based on diameter of circle
                int pressedX = (int)mousePt.getX();
                int pressedY = (int)mousePt.getY();
                pressedNodeID = getSelectedNodeIndexInExistingdNodes(pressedX, pressedY);
            
                if (pressedNodeID !=-1) {
                    m_pressedNodeID = pressedNodeID;
                    m_pressedNodeType = Constants.NODE_TYPE_COMPLETED;
                    //setSingleSelectedNodeID(pressedNodeID);
                    //System.out.println("mouse pressed on node " + pressedNodeID +" detected\n");
                    return;
                }
                pressedNodeID = getSelectedNodeIndexInNewNodes(pressedX, pressedY);
                if (pressedNodeID !=-1) {
                    m_pressedNodeID = pressedNodeID;
                    m_pressedNodeType = Constants.NODE_TYPE_PROTOTYPE;
                    //setSingleSelectedNodeID(pressedNodeID);
                    //System.out.println("mouse pressed on new node detected\n");
                    return;
                }
            }
        }
    }
    class MyMouseMotionListener extends MouseMotionAdapter {
        
        public void mouseDragged(MouseEvent e) {
            Point mousePt = e.getPoint();
            int clickedX = (int)mousePt.getX();
            int clickedY = (int)mousePt.getY();
            int newX_tl = clickedX - Constants.NODE_IMAGE_WIDTH/2;
            int newY_tl = clickedY - Constants.NODE_IMAGE_HEIGHT/2;
            double realX_ct = clickedX/Constants.NODE_IMAGE_DISTANCE_SCALE; 
            double realY_ct = clickedY/Constants.NODE_IMAGE_DISTANCE_SCALE;
                    
            if (m_pressedNodeID!=-1 && m_pressedNodeType == Constants.NODE_TYPE_COMPLETED) {
                m_graphicNodes.get(m_pressedNodeID).Xcoord = clickedX;//newX_tl;
                m_graphicNodes.get(m_pressedNodeID).Ycoord = clickedY;//newY_tl;
                m_networkTopo.nodes.get(m_pressedNodeID).setLocation((float) realX_ct, (float) realY_ct);
                m_networkTopo.calculateAdjacency();
                repaint();
            }
            if (m_pressedNodeID!=-1 && m_pressedNodeType == Constants.NODE_TYPE_PROTOTYPE) {
                m_graphicNewNodes.get(m_pressedNodeID).Xcoord = clickedX;
                m_graphicNewNodes.get(m_pressedNodeID).Ycoord = clickedY;
                m_newNodes.get(m_pressedNodeID).setLocation((float) realX_ct, (float) realY_ct);
                //m_networkTopo.calculateAdjacency();
                repaint();
            }
        }
    }
}
